package com.winshare.saleAssistant.service.impl;

import com.google.common.collect.Lists;
import com.winshare.saleAssistant.dao.OrganizationMapper;
import com.winshare.saleAssistant.domain.dto.req.*;
import com.winshare.saleAssistant.domain.entity.OrganizationDO;
import com.winshare.saleAssistant.domain.query.OrganizationQuery;
import com.winshare.saleAssistant.domain.dto.resp.OrganizationRespDTO;
import com.winshare.saleAssistant.exception.BusinessException;
import com.winshare.saleAssistant.mapper.OrganizationMapStruct;
import com.winshare.saleAssistant.service.OrganizationService;
import com.winshare.saleAssistant.util.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrganizationServiceImpl implements OrganizationService {

    private final OrganizationMapper organizationMapper;

    public OrganizationServiceImpl(OrganizationMapper organizationMapper) {
        this.organizationMapper = organizationMapper;
    }

    @Override
    public Page<OrganizationRespDTO> getOrganizationList(OrganizationQueryDTO organizationReq) {
        OrganizationQuery organizationQuery= OrganizationMapStruct.INSTANCE.fromOrganizationReqDTO(organizationReq);
        organizationQuery.setOffsetIndex(organizationReq.getOffsetIndex());
        int totalCount = organizationMapper.queryOrganizationCount(organizationQuery);
        Integer pageIndex = organizationReq.getPageIndex();
        Integer pageSize = organizationReq.getPageSize();
        if(0 == totalCount) {
            return new Page<>(pageIndex,pageSize,totalCount,new ArrayList<>());
        }
        List<OrganizationDO> organizationDOList = organizationMapper.findOrgListByConditions(organizationQuery);
        List<OrganizationRespDTO> organizationRespDTOList =
                OrganizationMapStruct.INSTANCE.toOrganizationRespDTO(organizationDOList);
        return new Page<>(pageIndex,pageSize,totalCount,organizationRespDTOList);
    }

    @Override
    public void save(OrganizationCreateDTO organizationCreateDTO) {
        organizationCreateDTO.validateOrgType();
        if(checkExist(organizationCreateDTO.getOrgCode(),organizationCreateDTO.getOrgName(),null)) {
            throw new BusinessException("机构名称或机构编码不能重复");
        }
        OrganizationDO organizationDO = OrganizationMapStruct.INSTANCE.fromOrganizationCreateDTO(organizationCreateDTO);
        organizationMapper.saveOrganization(organizationDO);
    }

    @Override
    public void update(OrganizationUpdateDTO organizationUpdateDTO) {
        organizationUpdateDTO.validateOrgType();
        if(checkExist(organizationUpdateDTO.getOrgCode(),organizationUpdateDTO.getOrgName(),
                organizationUpdateDTO.getId())) {
            throw new BusinessException("机构名称或机构编码不能重复");
        }
        OrganizationDO organizationDO = OrganizationMapStruct.INSTANCE.fromOrganizationUpdateDTO(organizationUpdateDTO);
        organizationMapper.updateOrganization(organizationDO);
    }

    @Override
    public void delete(OrganizationDeleteDTO organizationDeleteDTO) {
        OrganizationDO organizationDO = OrganizationMapStruct.INSTANCE.fromOrganizationDeleteDTOI(organizationDeleteDTO);
        organizationMapper.deleteOrganization(organizationDO);
    }

    @Override
    public OrganizationRespDTO getOrganizationDetail(BaseIdDTO baseIdDTO) {
        OrganizationDO organizationDO = OrganizationMapStruct.INSTANCE.fromBaseIdDTO(baseIdDTO);
        OrganizationDO organizationDOInSql = organizationMapper.getOrganization(organizationDO);
        if(null == organizationDOInSql) {
            throw new BusinessException("当前机构不存在");
        }
        OrganizationRespDTO organizationRespDTO = OrganizationMapStruct.INSTANCE.fromOrganizationDO(organizationDOInSql);
        return organizationRespDTO;
    }

    @Override
    public List<Integer> getChildrenOrgList(Integer orgId,String orgType) {
        List<Integer> orgIdList = Lists.newArrayList(orgId);
        List<Integer> tmpOrgList = orgIdList;
        while (orgId != 0  ) {
            List<Integer> childOrgIdList = organizationMapper.getChildrenOrgIdList(tmpOrgList,orgType);
            tmpOrgList = childOrgIdList;
            orgIdList.addAll(childOrgIdList.stream().collect(Collectors.toSet()));
            if(CollectionUtils.isEmpty(tmpOrgList)) {
                break;
            }
        }
        return orgIdList;
    }

    private boolean checkExist(String orgCode, String orgName, Integer orgId) {
        return organizationMapper.countByOrgCodeOrOrgName(orgCode, orgName, orgId) > 0;
    }
}
